﻿using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;

namespace Vbyte.SharpOrm.Util
{
    /// <summary>
    /// 通用功能函数实现
    /// </summary>
    public static class Common
    {
        /// <summary>
        /// 日志记录辅助
        /// </summary>
        /// <param name="logFileName">日志文件名，不包含扩展名。</param>
        /// <param name="writer">记录日志方法</param>
        public static void Log(string logFileName, Action<TextWriter> writer)
        {
            Log(logFileName, false, 1, ".log", writer);
        }

        /// <summary>
        /// 日志记录辅助(堆栈调用信息支持)
        /// </summary>
        /// <param name="logFileName">日志文件名，不包含扩展名。</param>
        /// <param name="showStackTrace">是否输出堆栈调用信息，此参数设置为true后将忽略跳过帧数的参数。</param>
        /// <param name="skipFrame">不记录堆栈时获取被调用方法跳过的帧数，此参数有效showStackTrace参数必须为false。</param>
        /// <param name="fileExt">日志文件的扩展名，形如".log"。</param>
        /// <param name="writer">记录日志方法</param>
        public static void Log(string logFileName, bool showStackTrace, int skipFrame, string fileExt, Action<TextWriter> writer)
        {
            lock (typeof(Common))
            {
                string customDir = string.Empty;
                if (logFileName.IndexOfAny(new char[] { '/', '\\' }) != -1)
                {
                    logFileName = logFileName.Replace("/", "\\");
                    int fnameIdx = logFileName.LastIndexOf('\\');
                    customDir = logFileName.Substring(0, fnameIdx);
                    logFileName = logFileName.Substring(fnameIdx);
                }

                DirectoryInfo logDir = new DirectoryInfo(string.Concat(AppDomain.CurrentDomain.BaseDirectory, "\\Logs\\", customDir));
                if (!logDir.Exists) logDir.Create();
                using (StreamWriter sw = new StreamWriter(String.Concat(logDir.FullName, "\\", logFileName, fileExt), true))
                {
                    sw.WriteLine("---TimeFlag @ {0} ThreadId:({1})---", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff"),
                        System.Threading.Thread.CurrentThread.ManagedThreadId);
                    if (!showStackTrace)
                    {
                        StackFrame invokeFrame = new StackFrame(skipFrame);
                        MethodBase method = invokeFrame.GetMethod();
                        sw.WriteLine("Invoke By: {0}::{1}", method.ReflectedType.IsGenericType ?
                            method.ReflectedType.FullName.Replace("`1", "<" + method.ReflectedType.GetGenericArguments()[0].ToString() + ">")
                            : method.ReflectedType.FullName
                            , method.Name);
                        //sw.WriteLine("Invoke By: {0}::{1}", method.ReflectedType.AssemblyQualifiedName, method.Name);
                    }
                    else
                    {
                        sw.WriteLine(new StackTrace(true).ToString());
                    }
                    writer(sw);
                    sw.Close();
                }
            }

        }

        /// <summary>
        /// 日志记录辅助(堆栈调用信息支持)
        /// </summary>
        /// <param name="logFileName">日志文件名，不包含扩展名。</param>
        /// <param name="showStackTrace">是否输出堆栈调用信息</param>
        /// <param name="writer">记录日志方法</param>
        public static void Log(string logFileName, bool showStackTrace, Action<TextWriter> writer)
        {
            Log(logFileName, showStackTrace, 3, ".log", writer);
        }

    }
}
